package team.seekers.hula.course.resource.sectionContent.service;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import team.seekers.hula.course.course.entity.dto.CourseLearnedProcessDTO;
import team.seekers.hula.course.resource.problem.entity.vo.ProblemVO;
import team.seekers.hula.course.resource.problem.service.ProblemService;
import team.seekers.hula.course.resource.sectionContent.dao.SectionContentDao;
import team.seekers.hula.course.resource.sectionContent.entity.dto.*;
import team.seekers.hula.course.resource.sectionContentComment.entity.vo.SectionContentCommentListVO;
import team.seekers.hula.course.resource.sectionContentComment.service.SectionContentCommentService;
import team.seekers.hula.course.structure.section.dao.SectionProgressDao;
import team.seekers.hula.course.resource.sectionContent.entity.dao.SectionContentDO;
import team.seekers.hula.course.structure.section.entity.dao.SectionProgressDO;
import team.seekers.hula.course.resource.sectionContent.entity.vo.SectionContentListVO;
import team.seekers.hula.course.resource.sectionContent.entity.vo.SectionContentVO;
import team.seekers.hula.course.structure.section.service.SectionProgressService;
import team.seekers.hula.course.structure.section.service.SectionService;
import team.seekers.hula.system.resource.entity.dto.VideoDTO;
import team.seekers.hula.system.resource.service.VideoService;

import java.util.*;

/**
 * date: 2022/4/30 19:33
 *
 * @author GH
 * QQ 1124813753
 */
@Slf4j
@Service
public class SectionContentService {



    @Autowired
    private SectionContentDao sectionContentDao;

    @Autowired
    private SectionProgressDao contentProcessDao;

    @Autowired
    private SectionService sectionService;

    @Autowired
    private SectionProgressService sectionProgressService;

    @Autowired
    private ProblemService problemService;

    @Autowired
    private VideoService videoService;

    @Autowired
    private SectionContentCommentService sectionContentCommentService;


    public SectionContentDTO queryById(Long sectionContentId) {
        SectionContentDO contentDO = sectionContentDao.getById(sectionContentId);
        SectionContentDTO sectionContentDTO = new SectionContentDTO();
        BeanUtils.copyProperties(contentDO,sectionContentDTO);
        return sectionContentDTO;
    }

    /**
     * 获得课程章节目录细节（用于课程管理）
     */
    public List<SectionContentListDTO> queryByIds(List<String> sectionContentIds) {
        if (CollectionUtils.isEmpty(sectionContentIds)) {
            return null;
        }

        List<SectionContentDO> contents = sectionContentDao.lambdaQuery()
                .in(SectionContentDO::getSectionId, sectionContentIds).list();

        ArrayList<SectionContentListDTO> contentListDTOS = new ArrayList<>();

        for (SectionContentDO sectionContentDO : contents) {
            SectionContentListDTO sectionContentListDTO = new SectionContentListDTO();
            BeanUtils.copyProperties(sectionContentDO,sectionContentListDTO);
            contentListDTOS.add(sectionContentListDTO);
        }
        return contentListDTOS;
    }



    /**
     * 获得课程章节目录细节（包括进度记录）
     */
    public List<SectionContentListDTO> querySectionContentsBySectionIdWithStatus(String sectionId, String userId) {
        List<SectionContentDO> contentDOList = sectionContentDao.lambdaQuery()
                .eq(SectionContentDO::getSectionId, sectionId)
                .ge(SectionContentDO::getSequence,1)
                .eq(SectionContentDO::getIsVisible, 1)
                .orderByAsc(SectionContentDO::getSequence)
                .list();

        ArrayList<SectionContentListDTO> contentListDTOS = new ArrayList<>();

        for (SectionContentDO sectionContentDO : contentDOList) {
            SectionContentListDTO sectionContentListDTO = new SectionContentListDTO();
            BeanUtils.copyProperties(sectionContentDO,sectionContentListDTO);
            contentListDTOS.add(sectionContentListDTO);
        }
        contentListDTOS.forEach(dto ->
                dto.setProgress(sectionProgressService.getProgressBySectionId(dto.getId(),userId)));
        return contentListDTOS;
    }


    /**
     * 获得课程章节目录细节（无进度记录）
     */
    public List<SectionContentListDTO> querySectionContentsBySectionId(String sectionId) {
        List<SectionContentDO> contentDOList = sectionContentDao.lambdaQuery().select().eq(SectionContentDO::getSectionId, sectionId).list();
        ArrayList<SectionContentListDTO> sectionContentListDTOS = new ArrayList<>();

        for (SectionContentDO sectionContentDO : contentDOList) {
            SectionContentListDTO sectionContentListDTO = new SectionContentListDTO();
            BeanUtils.copyProperties(sectionContentDO,sectionContentListDTO);
            sectionContentListDTOS.add(sectionContentListDTO);
        }
        return sectionContentListDTOS;
    }


    public String getContentById(String sectionContentId) {
        return sectionContentDao.getById(sectionContentId).getContent();
    }

    public SectionContentVO getContentInfo(String id, String userId) {
        SectionContentDO sectionContentDO = sectionContentDao.lambdaQuery()
                .eq(SectionContentDO::getId, id)
                .one();

        SectionContentVO sectionContentVO = new SectionContentVO();
        BeanUtils.copyProperties(sectionContentDO,sectionContentVO);
        if(sectionContentDO.getType() == 1){
            // 是视频
            VideoDTO videoDTO = videoService.queryInfoById(sectionContentDO.getContent());
            sectionContentVO.setPieces(JSON.parseArray(sectionContentDO.getPieces(), SectionContentPieceDTO.class));
            sectionContentVO.setVideo(videoDTO);
        }
        if(sectionContentDO.getType() == 2){
            // 是题目
            ProblemVO infoVO = problemService.getInfoVO(sectionContentDO.getContent());
            sectionContentVO.setProblem(infoVO);
        }

        // 获取所有的评论
        List<SectionContentCommentListVO> commentListVOS =  sectionContentCommentService.listOrderByTime(sectionContentDO.getId());

        if(sectionContentDO.getType() == 1){
            // 视频分片
            List<SectionContentPieceDTO> pieces = sectionContentVO.getPieces();
            for (int i = 0;i<pieces.size();i++) {
                if(i < pieces.size()-1){
                    pieces.get(i).setDuration(pieces.get(i+1).getStartTime() - pieces.get(i).getStartTime());
                }else{
                    pieces.get(i).setDuration(sectionContentVO.getVideo().getDuration()- pieces.get(i).getStartTime());
                }
                pieces.get(i).setComments(new ArrayList<>());
            }

            for (SectionContentCommentListVO commentListVO : commentListVOS) {
                for (SectionContentPieceDTO piece : pieces) {
                    if(commentListVO.getTime() >= piece.getStartTime() && commentListVO.getTime() < piece.getStartTime()+piece.getDuration()){
                        piece.getComments().add(commentListVO);
                    }
                }
            }
        } else {
            sectionContentVO.setComments(commentListVOS);
        }


        return sectionContentVO;
    }

    public Map<String, List<SectionContentListVO>> mapFourSectionContentByCourseIds(List<String> courseIds) {
        HashMap<String, List<SectionContentListVO>> longListHashMap = new HashMap<>();
        for (String courseId : courseIds) {
            List<SectionContentDO> list = sectionContentDao.lambdaQuery().select(
                    SectionContentDO::getId,
                    SectionContentDO::getCourseId,
                    SectionContentDO::getName,
                    SectionContentDO::getType
            ).eq(SectionContentDO::getCourseId, courseId).page(new Page<>(1,4)).getRecords();

            ArrayList<SectionContentListVO> sectionContentListVOS = new ArrayList<>();
            for (SectionContentDO sectionContentDO : list) {
                SectionContentListVO sectionContentListVO = new SectionContentListVO();
                BeanUtils.copyProperties(sectionContentDO,sectionContentListVO);
                sectionContentListVOS.add(sectionContentListVO);
            }
            longListHashMap.put(courseId,sectionContentListVOS);
        }
        return longListHashMap;
    }

    public List<SectionContentListVO> getAttachChapterAllSectionContentsById(String sectionContentId) {
        String sectionId = sectionContentDao.lambdaQuery().select(
                SectionContentDO::getSectionId
        ).eq(SectionContentDO::getId, sectionContentId).one().getSectionId();
        List<String> sectionIds =  sectionService.getAttachChapterAllSectionIdsById(sectionId);


        List<SectionContentListVO> sectionContentListVOS = new ArrayList<>();
        List<SectionContentDO> list = sectionContentDao.lambdaQuery().select(
                SectionContentDO::getId,
                SectionContentDO::getCourseId,
                SectionContentDO::getName,
                SectionContentDO::getType
        ).in(SectionContentDO::getSectionId, sectionIds).list();

        for (SectionContentDO sectionContentDO : list) {
            SectionContentListVO sectionContentListVO = new SectionContentListVO();
            BeanUtils.copyProperties(sectionContentDO,sectionContentListVO);
            sectionContentListVOS.add(sectionContentListVO);
        }

        return sectionContentListVOS;
    }

    public String getAttachChapterInfoById(String sectionContentId) {
        String sectionId = sectionContentDao.lambdaQuery().select(
                SectionContentDO::getSectionId
        ).eq(SectionContentDO::getId, sectionContentId).one().getSectionId();
        return sectionService.getAttachChapterNameById(sectionId);
    }

    public CourseLearnedProcessDTO queryLearnProcessBySectionIds(ArrayList<String> sectionIds, String userId) {

        ArrayList<String> sectionContentIds = new ArrayList<>();
        List<SectionContentDO> sectionContentDOList = sectionContentDao.lambdaQuery().select(
                SectionContentDO::getId
        ).in(SectionContentDO::getSectionId, sectionIds).list();
        for (SectionContentDO sectionContentDO : sectionContentDOList) {
            sectionContentIds.add(sectionContentDO.getId());
        }

        Integer sectionContentNum = sectionContentIds.size();
        Integer sectionContentLearnedNum = 0;
        String lastSectionContentId = "0L";
        String lastSectionContentName  = "";

        List<SectionProgressDO> sectionProgressDOList = contentProcessDao.lambdaQuery().select(
                SectionProgressDO::getId,
                SectionProgressDO::getSectionId,
                SectionProgressDO::getProgress
        ).in(SectionProgressDO::getSectionId, sectionContentIds).eq(SectionProgressDO::getUserId,userId).list();



        for (SectionProgressDO sectionProgressDO : sectionProgressDOList) {
            if(sectionProgressDO.getProgress() < 100){
                if(StringUtils.isNotBlank(lastSectionContentId)){
                    lastSectionContentId = sectionProgressDO.getSectionId();
                    lastSectionContentName = sectionContentDao.getById(lastSectionContentId).getName();
                }
            }else {
                sectionContentLearnedNum++;
            }
        }

        return CourseLearnedProcessDTO.builder()
                .sectionContentNum(sectionContentNum)
                .sectionContentLearnedNum(sectionContentLearnedNum)
                .lastSectionId(lastSectionContentId)
                .lastSectionContentName(lastSectionContentName).build();
    }

    public String save(SectionContentCreateDTO linkSectionContent) {
        SectionContentDO sectionContentDO = new SectionContentDO();
        BeanUtils.copyProperties(linkSectionContent,sectionContentDO);

        if(null != linkSectionContent.getPieces()){
            sectionContentDO.setPieces(JSON.toJSONString(linkSectionContent.getPieces()));
        }
        sectionContentDO.setIsVisible(1);
        sectionContentDao.save(sectionContentDO);
        return sectionContentDO.getId();
    }

    public List<SectionContentVO> getInfoListBySectionId(String id) {
        List<SectionContentDO> list = sectionContentDao.lambdaQuery()
                .eq(SectionContentDO::getSectionId, id)
                .ge(SectionContentDO::getSequence,1)
                .eq(SectionContentDO::getIsVisible, 1)
                .orderByAsc(SectionContentDO::getSequence)
                .list();

        ArrayList<SectionContentVO> sectionContentVOS = new ArrayList<>();
        for (SectionContentDO sectionContentDO : list) {
            SectionContentVO sectionContentVO = new SectionContentVO();
            BeanUtils.copyProperties(sectionContentDO,sectionContentVO);
            if(sectionContentDO.getType() == 1){
                // 是视频
                VideoDTO videoDTO = videoService.queryInfoById(sectionContentDO.getContent());
                sectionContentVO.setVideo(videoDTO);
            }
            if(sectionContentDO.getType() == 2){
                // 是题目
                ProblemVO infoVO = problemService.getInfoVO(sectionContentDO.getContent());
                sectionContentVO.setProblem(infoVO);
            }
            sectionContentVOS.add(sectionContentVO);
        }
        return sectionContentVOS;
    }



    public SectionContentDTO getBindContentBySectionId(String sectionId) {
        SectionContentDO sectionContentDO = sectionContentDao.lambdaQuery()
                .select(SectionContentDO::getContent, SectionContentDO::getId)
                .eq(SectionContentDO::getSectionId, sectionId)
                .eq(SectionContentDO::getSequence, 0)
                .eq(SectionContentDO::getIsVisible, 1)
                .one();
        SectionContentDTO sectionContentDTO = new SectionContentDTO();
        BeanUtils.copyProperties(sectionContentDO,sectionContentDTO);
        return sectionContentDTO;
    }

    public String getCourseIdById(String sectionContentId) {
        return sectionContentDao.lambdaQuery().select(SectionContentDO::getCourseId).eq(SectionContentDO::getId,sectionContentId).one().getCourseId();
    }

    public ArrayList<String> getBindContentIdListBySectionId(String sectionId) {
        List<SectionContentDO> list = sectionContentDao.lambdaQuery().select(
                SectionContentDO::getId
        ).eq(SectionContentDO::getSectionId, sectionId).list();

        ArrayList<String> ids = new ArrayList<>();
        for (SectionContentDO sectionContentDO : list) {
            ids.add(sectionContentDO.getId());
        }

        return ids;
    }

    public SectionContentDTO update(SectionContentUpdateDTO updateDTO) {
        SectionContentDO sectionContentDO = sectionContentDao.getById(updateDTO.getId());
        BeanUtils.copyProperties(updateDTO,sectionContentDO);

        Integer version = sectionContentDao.lambdaQuery().select(SectionContentDO::getVersion)
                .eq(SectionContentDO::getSectionId, sectionContentDO.getSectionId())
                .eq(SectionContentDO::getSequence, sectionContentDO.getSequence())
                .count();

        sectionContentDO.setVersion(version);
        sectionContentDO.setId(null);
        sectionContentDao.save(sectionContentDO);

        sectionContentDao.lambdaUpdate()
                .set(SectionContentDO::getIsVisible,0)
                .eq(SectionContentDO::getId,updateDTO.getId())
                .update();

        return SectionContentDO.toDTO(sectionContentDO);
    }
}
